//盒子对象
var box = document.querySelector(".box");
//棋盘对象绘制棋盘
var board = document.querySelector(".draw-board");
//棋盘遮罩放置棋子
var boardMask = document.querySelector(".mask");

//信息框
var messageBox = document.querySelector(".messageBox");
//信息框确定按钮
var confirm = document.querySelector(".confirm");
//信息框提示文本
var text = document.querySelector(".text");
//关闭信息框
var close = document.querySelector(".close");


//开始游戏按钮
var startBtn = document.querySelector(".start");
//悔棋按钮
var backBtn = document.querySelector(".back");
//计步按钮
var stepBtn = document.querySelector(".step");


//设置游戏为未开始
var start = false;
//设置当前落子为黑棋
var pieceColor = "black";
//设置计步是否启动
var step = false;
//是否可以悔棋
var backFlag = false;

//存储每一颗棋子信息[{point:{X:1,Y:2},color:"black"}]
var pieceInfoArray = [];

//"开始游戏"按钮单击
startBtn.addEventListener("click", function () {
    clear(boardMask);//清除棋盘所有棋子
    pieceInfoArray = [];//清除存储的所有棋子信息
    start = true;//设置游戏为开始
    backFlag = true;//可以悔棋
    pieceColor = "black";//设置当前落子为黑子
    messageBox.style.display = "none";//隐藏信息框
});

//"悔棋"按钮单击
backBtn.addEventListener("click", function () {
    backPiece(backFlag);//删除最后一颗落子
});

//"计步"按钮单击
stepBtn.addEventListener("click", function () {

    if (stepBtn.innerHTML == "开启计步") {
        step = true;
        stepBtn.innerHTML = "关闭计步"
    } else if (stepBtn.innerHTML == "关闭计步") {
        step = false;
        stepBtn.innerHTML = "开启计步"
    }
    stepInfo(step);//为每一颗棋子添加索引
});

//关闭信息框
close.addEventListener("click", function () {
    messageBox.style.display = "none";//隐藏信息框
});

box.addEventListener("click", function (e) {
    //鼠标在棋盘方格内的横坐标
    var x = e.pageX - box.offsetLeft - 25;
    //鼠标在棋盘方格内的纵坐标
    var y = e.pageY - box.offsetTop - 25;

    //棋盘交叉点坐标索引
    var crossPoint = getCrossPoint(x, y);

    //游戏是未开始状态或未正确获取到棋子坐标,则返回
    if (start == false || crossPoint[0] * crossPoint[1] < 0) {
        return;
    }

    //当前位置是否存在棋子
    if (exist(crossPoint, pieceInfoArray)) {
        return;
    }

    //获取棋子信息
    var pieceInfo = {
        //棋子坐标
        point: [crossPoint[0], crossPoint[1]],
        //棋子颜色
        color: pieceColor
    }

    //创建棋子
    var piece = document.createElement("div");
    //设置棋子样式
    piece.className = "piece";
    //设置棋子绝对定位左边距
    piece.style.left = crossPoint[0] * 50 + 5 + "px";
    //设置棋子绝对定位上边距
    piece.style.top = crossPoint[1] * 50 + 5 + "px";
    //判断当前落子的是黑棋还是白棋
    if (pieceColor == "black") {
        //设置为黑棋
        piece.style.backgroundColor = "#000";
        pieceColor = "white"
    } else {
        //设置为白棋
        piece.style.backgroundColor = "#fff";
        pieceColor = "black";
    }
    //棋子加入棋盘
    boardMask.appendChild(piece);
    //计步
    if (step) {
        stepInfo(step);
    }
    //棋子信息加入数组
    pieceInfoArray.push(pieceInfo);
    //获取胜利方
    var winColor = getWin(pieceInfoArray);
    if (winColor) {
        //禁止悔棋
        backFlag = false;
        //设置信息框信息
        info(winColor);
        //显示信息框
        messageBox.style.display = "block";
    }
});



/**
 * 获取棋盘交叉点索引坐标
 * @param {number} x 鼠标在棋盘方格内横坐标
 * @param {number} y 鼠标在棋盘方格内纵坐标
 */
function getCrossPoint(x, y) {

    //棋盘交叉点索引坐标
    var crossPointX, crossPointY;
    //若鼠标在交叉线横向左右20px内点击,返回交叉线的横坐标
    if (x % 50 >= 30) {
        crossPointX = parseInt(x / 50) + 1;
    } else if (x % 50 <= 20 || x % 50 >= -20) {
        crossPointX = parseInt(Math.abs(x / 50));
    } else {
        crossPointX = -1;
    }
    //若鼠标在交叉线竖向上下20px内点击,返回交叉线的纵坐标
    if (y % 50 >= 30) {
        crossPointY = parseInt(y / 50) + 1;
    } else if (y % 50 <= 20 || y % 50 >= -20) {
        crossPointY = parseInt(Math.abs(y / 50));
    } else {
        crossPointY = -1;
    }
    //返回棋盘交叉点的横纵坐标,[0,0]到[9,9]
    return [crossPointX, crossPointY];
}


/**
 * 获取胜利方
 * @param {*} pieceInfoArray 存储棋子信息数组
 */
function getWin(pieceInfoArray) {
    //最后落子的棋子信息
    var pieceInfo = pieceInfoArray[pieceInfoArray.length - 1];
    //棋子颜色
    var pieceColor = pieceInfo.color;
    //棋子横坐标
    var crossPointX = pieceInfo.point[0];
    //棋子纵坐标
    var crossPointY = pieceInfo.point[1];
    //双层循环,从八个方向判断一条线上是否有五个同色棋子
    for (var i = -1; i <= 1; i++) {
        for (var j = -1; j <= 1; j++) {
            //一共八条线路,原点不用判断
            if (i == 0 && j == 0) {
                continue;
            }

            var direction_i = i;//方向变量X
            var direction_j = j;//方向变量Y
            var step = 1;//步长
            var count = 1;//记录同色棋子个数
            var reversal = 0;//反转次数

            while (true) {

                //获取棋子坐标
                var x = crossPointX + step * direction_i;
                var y = crossPointY + step * direction_j;

                //判断当前线路是否有同色棋子在棋盘中
                if (exist([x, y], pieceInfoArray) == pieceColor) {

                    count++;//同色棋子个数加1

                    //同色棋子个数为5,游戏胜利,返回获胜的棋子颜色
                    if (count == 5) {
                        return pieceColor;
                    }
                    step++;//步长加1

                } else {
                    reversal++;//反转次数加一
                    //当反转次数为2时,结束当前循环,当前线路没有五个同色棋子
                    if (reversal == 2) {
                        break;
                    }
                    direction_i = -i;//线路反转,X方向改变
                    direction_j = -j;//线路反转,Y方向改变
                    step = 1;//当前线路反转,步长重新设置为1

                }
            }
        }
    }
}


//设置棋子的样式
function setPieceStyle(piece, pieceLocation) {
    //设置棋子绝对定位
    piece.style.position = "absolute";
    //设置棋子宽
    piece.style.width = "40px";
    //设置棋子高
    piece.style.height = "40px";
    //设置棋子为圆形
    piece.style.borderRadius = "50%";
    //设置鼠标样式
    piece.style.cursor = "default";
    //设置棋子绝对定位左边距
    piece.style.left = pieceLocation[0] * 50 + 5 + "px";
    //设置棋子绝对定位上边距
    piece.style.top = pieceLocation[1] * 50 + 5 + "px";
}


/**
 * 信息框设置
 * @param {string} color 获胜的棋子颜色
 */
function info(color) {
    start = false;//游戏设置为未开始
    //判断赢家
    if (color == "black") {
        text.innerHTML = "黑棋获胜";
    } else {
        text.innerHTML = "白棋获胜";
    }
    //按钮单击事件
    confirm.addEventListener("click", function () {
        messageBox.style.display = "none";
    });
}


/**
 * 清除所有棋子和坐标数组
 * @param {Object} 放置棋子的元素对象
 */
function clear(ele) {
    //清除棋盘所有棋子
    while (ele.children.length != 0) {
        ele.removeChild(ele.children[0]);
    }
}

/**
 * 悔棋
 * @param {boolean} backFlag 是否可以悔棋
 */
function backPiece(backFlag) {
    if (!backFlag) return;
    boardMask.removeChild(boardMask.lastElementChild);//删除棋盘最后一颗棋子
    //悔棋后设置下次棋子为悔棋的颜色
    pieceColor = pieceInfoArray[pieceInfoArray.length - 1].color;
    pieceInfoArray.pop();//删除存储的最后一颗棋子的信息
}

/**
 * 开启计步
 * @param {boolean} step 是否开启计步
 */
function stepInfo(step) {
    //为每一颗棋子设置索引
    if (step) {
        for (var i = 0; i < boardMask.children.length; i++) {
            boardMask.children[i].style.lineHeight = "40px";
            boardMask.children[i].style.color = "red";
            boardMask.children[i].style.textAlign = "center";
            boardMask.children[i].innerHTML = i + 1;
        }
    } else {//关闭计步则清空索引
        for (var i = 0; i < boardMask.children.length; i++) {
            boardMask.children[i].innerHTML = "";
        }
    }

}

/**
 * 判断当前坐标是否存在棋子,存在则返回棋子颜色
 * @param {number[]} crossPoint 当前坐标
 * @param {number[]} pieceInfoArray 存储棋盘上棋子坐标的数组
 */
function exist(crossPoint, pieceInfoArray) {
    for (var i = 0; i < pieceInfoArray.length; i++) {
        if (pieceInfoArray[i].point[0] == crossPoint[0] && pieceInfoArray[i].point[1] == crossPoint[1]) {
            return pieceInfoArray[i].color;
        }
    }
    return null;
}